﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Odyssey.ViewModels;
using System.Collections.Generic;
using System.Collections;
using System.Collections.ObjectModel;
using System.Windows.Threading;
using Odyssey.Utils;

namespace Odyssey.Controls.Models
{
    /// <summary>
    /// Used by OdcListBox to exchange data with the quick jump list.
    /// </summary>
    public class QuickJumpViewModel : ViewModelBase
    {
        const string indexChars = "#abcdefghijklmnopqrstuvwxyz";


        public QuickJumpViewModel()
            : base()
        {
            CreateItemsList();
        }

        protected virtual void CreateItemsList()
        {
            Items = new List<QuickJumpItem>(indexChars.Length);
            foreach (char c in indexChars)
            {
                Items.Add(new QuickJumpItem(c.ToString()));
            }
        }

        private QuickJumpItem selectedItem;
        private bool isOpened = true;

        public bool IsOpened
        {
            get { return isOpened; }
            set
            {
                if (isOpened != value)
                {
                    isOpened = value;
                    OnPropertyChanged("IsOpened");
                }
            }
        }

        public Overlay Overlay;

        public QuickJumpItem SelectedItem
        {
            get { return selectedItem; }
            set
            {
                if (selectedItem != value)
                {
                    selectedItem = value;
                    OnPropertyChanged("SelectedItem");
                    OnSelectedItemChanged(value);
                }
            }
        }

        public OdcListBox ListBox { get; set; }

        public List<QuickJumpItem> Items { get; protected set; }

        private int jumpIndex = -1;

        private void OnSelectedItemChanged(QuickJumpItem item)
        {
            var lb = ListBox;
            if (ListBox != null && item != null)
            {
                IList itemsSource = ListBox.ItemsSource;
                int index = item.JumpIndex;
                SelectedItem = null;


                Overlay.IsOpen = false;
                if (index >= 0 && index < itemsSource.Count)
                {
                    jumpIndex = index;
                    // this is made dispatched a second time to ensure that it the listbox has the size excluding the application bar if available:
//                    Dispatcher.BeginInvoke(() => lb.SetQuickJumpIndex(index));
                    lb.SetQuickJumpIndex(index);
//                    this.Overlay.RestoreApplicationBar();
                }
                IsOpened = false;
                lb.IsJumpListOpen = false;

            }
        }

        public virtual void UpdateFromItemsSource(IList itemsSource)
        {
            SelectedItem = null;
            Dictionary<int, int> enabledItems = new Dictionary<int, int>(indexChars.Length);

            int n = itemsSource.Count;
            for (int i = 0; i < n; i++)
            {
                IGroupItem item = itemsSource[i] as IGroupItem;
                if (item != null && item.IsHeader)
                {
                    int index = GetIndexFromName(item.GroupName);
                    enabledItems.Add(index, i);
                }
            }
            for (int i = 0; i < Items.Count; i++)
            {
                QuickJumpItem item = Items[i];
                bool isEnabled = enabledItems.ContainsKey(i);
                item.IsEnabled = isEnabled;
                item.JumpIndex = isEnabled ? enabledItems[i] : -1;
            }
        }

        public void HandleQuickJumpListClosing(object sender, EventArgs e)
        {
            int index = jumpIndex;
            var listBox = ListBox;
            IsOpened = false;
        }

        public void HandleQuickJumpListClosed(object sender, EventArgs e)
        {

            Overlay overlay = sender as Overlay;
            overlay.Closing -= HandleQuickJumpListClosing;
            overlay.Closed -= HandleQuickJumpListClosed;

            var lb = ListBox;
            ListBox.IsJumpListOpen = false;

            ListBox = null;
            jumpIndex = -1;
        }

        protected virtual int GetIndexFromName(string name)
        {
            if (string.IsNullOrEmpty(name)) return 0;
            string c = name.Substring(0, 1);
            int index = indexChars.IndexOf(c, StringComparison.InvariantCultureIgnoreCase);
            return index >= 0 ? index : 0;
        }
    }
}
